package com.nnnu.wsnackshop.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nnnu.wsnackshop.exception.ObjectException;
import com.nnnu.wsnackshop.mapper.UsersMapper;
import com.nnnu.wsnackshop.mapper.OrderItemsMapper;
import com.nnnu.wsnackshop.pojo.entity.Reviews;
import com.nnnu.wsnackshop.mapper.ReviewsMapper;
import com.nnnu.wsnackshop.pojo.entity.OrderItems;
import com.nnnu.wsnackshop.pojo.vo.ReviewVO;
import com.nnnu.wsnackshop.service.IReviewsService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * 评价 服务实现类
 * </p>
 *
 * @author zk
 * @since 2025-05-14
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class ReviewsServiceImpl extends ServiceImpl<ReviewsMapper, Reviews> implements IReviewsService {

    private final UsersMapper usersMapper;
    private final OrderItemsMapper orderItemsMapper;

    @Override
    public List<ReviewVO> listReviewsByProduct(Integer productId, Integer limit) {
        LambdaQueryWrapper<Reviews> qw = Wrappers.<Reviews>lambdaQuery()
                .eq(Reviews::getProductId, productId)
                .orderByDesc(Reviews::getCreatedAt);

        // 限制查询数量
        if (limit != null && limit > 0) {
            qw.last("LIMIT " + limit);
        }

        List<Reviews> reviews = baseMapper.selectList(qw);

        if (reviews.isEmpty()) {
            return Collections.emptyList();
        }
        // 转换为 VO 并填充用户信息
        return reviews.stream().map(this::getReviewVO).collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ReviewVO createReview(Integer userId, Integer productId, Long orderId, Integer skuId, Integer rating,
                                 String comment, String images) {
        log.info("创建评价: userId={}, productId={}, orderId={}, rating={}", userId, productId, orderId, rating);

        // 检查评分是否有效
        if (rating < 1 || rating > 5) {
            throw new ObjectException("评分必须在1-5星之间");
        }

        // 检查是否已经评价过
        LambdaQueryWrapper<Reviews> existCheckQw = Wrappers.<Reviews>lambdaQuery()
                .eq(Reviews::getUserId, userId)
                .eq(Reviews::getProductId, productId)
                .eq(Reviews::getOrderId, orderId);

        if (baseMapper.selectCount(existCheckQw) > 0) {
            throw new ObjectException("您已经评价过该商品");
        }

        // 创建评价记录
        Reviews review = new Reviews();
        review.setUserId(userId);
        review.setProductId(productId);
        review.setOrderId(orderId);
        review.setRating(rating);
        review.setComment(comment);
        review.setImages(images);
        review.setCreatedAt(LocalDateTime.now());

        // 保存评价
        baseMapper.insert(review);

        // 更新订单项的评价状态
        LambdaUpdateWrapper<OrderItems> updateWrapper = Wrappers.<OrderItems>lambdaUpdate()
                .eq(OrderItems::getOrderId, orderId)
                .eq(OrderItems::getProductId, productId)
                .eq(OrderItems::getSkuId, skuId)
                .set(OrderItems::getReviewStatus, 1); // 1=已评价

        orderItemsMapper.update(null, updateWrapper);

        // 转换为 VO
        return getReviewVO(review);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ReviewVO updateReview(Integer reviewId, Integer userId, Integer rating, String comment, String images) {
        log.info("更新评价: reviewId={}, userId={}, rating={}", reviewId, userId, rating);

        // 检查评分是否有效
        if (rating < 1 || rating > 5) {
            throw new ObjectException("评分必须在1-5星之间");
        }

        // 获取评价记录
        Reviews review = baseMapper.selectById(reviewId);
        if (review == null) {
            throw new ObjectException("评价不存在");
        }

        // 检查是否是评价的所有者
        if (!review.getUserId().equals(userId)) {
            throw new ObjectException("您无权修改此评价");
        }

        // 更新评价内容
        review.setRating(rating);
        review.setComment(comment);
        review.setImages(images);

        // 保存更新
        baseMapper.updateById(review);

        return getReviewVO(review);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteReview(Integer reviewId, Integer userId) {
        log.info("删除评价: reviewId={}, userId={}", reviewId, userId);

        // 获取评价记录
        Reviews review = baseMapper.selectById(reviewId);
        if (review == null) {
            throw new ObjectException("评价不存在");
        }

        // 检查是否是评价的所有者
        if (!review.getUserId().equals(userId)) {
            throw new ObjectException("您无权删除此评价");
        }

        // 获取订单ID和商品ID以更新订单项评价状态
        Long orderId = review.getOrderId();
        Integer productId = review.getProductId();

        // 删除评价
        int deleteResult = baseMapper.deleteById(reviewId);

        if (deleteResult > 0 && orderId != null && productId != null) {
            // 更新订单项的评价状态为未评价
            LambdaUpdateWrapper<OrderItems> updateWrapper = Wrappers.<OrderItems>lambdaUpdate()
                    .eq(OrderItems::getOrderId, orderId)
                    .eq(OrderItems::getProductId, productId)
                    .set(OrderItems::getReviewStatus, 0); // 0=未评价

            orderItemsMapper.update(null, updateWrapper);
            return true;
        }

        return deleteResult > 0;
    }

    @Override
    public List<ReviewVO> listUserReviews(Integer userId, Integer page, Integer size) {
        log.info("获取用户评价: userId={}, page={}, size={}", userId, page, size);

        // 默认分页参数
        page = (page == null || page < 1) ? 1 : page;
        size = (size == null || size < 1) ? 10 : size;

        // 分页查询
        IPage<Reviews> pageParam = new Page<>(page, size);
        LambdaQueryWrapper<Reviews> queryWrapper = Wrappers.<Reviews>lambdaQuery()
                .eq(Reviews::getUserId, userId)
                .orderByDesc(Reviews::getCreatedAt);

        IPage<Reviews> pageResult = baseMapper.selectPage(pageParam, queryWrapper);

        if (pageResult.getRecords().isEmpty()) {
            return Collections.emptyList();
        }

        // 转换为 VO 并填充用户信息
        return pageResult.getRecords().stream().map(this::getReviewVO).collect(Collectors.toList());
    }

    @Override
    public List<ReviewVO> listReviewsByOrder(Long orderId) {
        log.info("获取订单评价: orderId={}", orderId);

        LambdaQueryWrapper<Reviews> qw = Wrappers.<Reviews>lambdaQuery()
                .eq(Reviews::getOrderId, orderId)
                .orderByDesc(Reviews::getCreatedAt);

        List<Reviews> reviews = baseMapper.selectList(qw);

        if (reviews.isEmpty()) {
            return Collections.emptyList();
        }
        // 转换为 VO 并填充用户信息
        return reviews.stream().map(this::getReviewVO).collect(Collectors.toList());
    }


    @Override
    public ReviewVO getReviewByOrderAndProduct(Long orderId, Integer productId) {
        log.info("获取订单商品评价: orderId={}, productId={}", orderId, productId);

        LambdaQueryWrapper<Reviews> qw = Wrappers.<Reviews>lambdaQuery()
                .eq(Reviews::getOrderId, orderId)
                .eq(Reviews::getProductId, productId);

        Reviews review = baseMapper.selectOne(qw);

        if (review == null) {
            return null;
        }
        // 转换为 VO
        return getReviewVO(review);
    }

    @Override
    public Page<ReviewVO> pageReviewsByProduct(Integer productId, Integer page, Integer pageSize,
                                               Integer minRating, Integer maxRating, Boolean hasImages) {
        log.info("分页获取商品评价: productId={}, page={}, pageSize={}, minRating={}, maxRating={}, hasImages={}",
                productId, page, pageSize, minRating, maxRating, hasImages);

        // 默认分页参数
        page = (page == null || page < 1) ? 1 : page;
        pageSize = (pageSize == null || pageSize < 1) ? 10 : pageSize;

        // 构建查询条件
        LambdaQueryWrapper<Reviews> queryWrapper = Wrappers.<Reviews>lambdaQuery()
                .eq(Reviews::getProductId, productId)
                .ge(minRating != null, Reviews::getRating, minRating)
                .le(maxRating != null, Reviews::getRating, maxRating);

        // 如果需要查询有图片的评价
        if (Boolean.TRUE.equals(hasImages)) {
            queryWrapper.isNotNull(Reviews::getImages)
                    .ne(Reviews::getImages, "")
                    .ne(Reviews::getImages, "[]");
        }

        // 按创建时间倒序排序
        queryWrapper.orderByDesc(Reviews::getCreatedAt);

        // 执行分页查询
        Page<Reviews> pageParam = new Page<>(page, pageSize);
        Page<Reviews> pageResult = baseMapper.selectPage(pageParam, queryWrapper);

        // 转换结果为VO
        Page<ReviewVO> voPage = new Page<>();
        BeanUtil.copyProperties(pageResult, voPage, "records");

        // 处理记录
        if (!pageResult.getRecords().isEmpty()) {
            List<ReviewVO> voList = pageResult.getRecords().stream().map(review -> {
                ReviewVO vo = BeanUtil.copyProperties(review, ReviewVO.class);

                // 填充用户信息
                Optional.ofNullable(usersMapper.selectById(review.getUserId()))
                        .ifPresent(member -> {
                            vo.setUsername(member.getNickname());
                            vo.setUserAvatar(member.getAvatar());
                        });
                return vo;
            }).collect(Collectors.toList());

            voPage.setRecords(voList);
        } else {
            voPage.setRecords(Collections.emptyList());
        }

        return voPage;
    }

    @Override
    public Map<String, Object> getReviewStats(Integer productId) {
        log.info("获取商品评价统计: productId={}", productId);

        // 商品总评价数
        long totalReviews = baseMapper.selectCount(
                Wrappers.<Reviews>lambdaQuery().eq(Reviews::getProductId, productId));

        // 统计各分数段评价数量
        long goodReviews = baseMapper.selectCount(
                Wrappers.<Reviews>lambdaQuery()
                        .eq(Reviews::getProductId, productId)
                        .ge(Reviews::getRating, 4));

        long mediumReviews = baseMapper.selectCount(
                Wrappers.<Reviews>lambdaQuery()
                        .eq(Reviews::getProductId, productId)
                        .ge(Reviews::getRating, 2)
                        .le(Reviews::getRating, 3));

        long badReviews = baseMapper.selectCount(
                Wrappers.<Reviews>lambdaQuery()
                        .eq(Reviews::getProductId, productId)
                        .le(Reviews::getRating, 1));

        // 统计有图评价数量
        long hasImageReviews = baseMapper.selectCount(
                Wrappers.<Reviews>lambdaQuery()
                        .eq(Reviews::getProductId, productId)
                        .isNotNull(Reviews::getImages)
                        .ne(Reviews::getImages, "")
                        .ne(Reviews::getImages, "[]"));

        // 计算平均评分
        double averageRating = 0;
        if (totalReviews > 0) {
            LambdaQueryWrapper<Reviews> qw = Wrappers.<Reviews>lambdaQuery()
                    .eq(Reviews::getProductId, productId)
                    .select(Reviews::getRating);

            List<Reviews> ratingList = baseMapper.selectList(qw);

            if (!ratingList.isEmpty()) {
                int ratingSum = ratingList.stream()
                        .mapToInt(review -> review.getRating() != null ? review.getRating() : 0)
                        .sum();

                averageRating = (double) ratingSum / ratingList.size();
                // 保留一位小数
                averageRating = Math.round(averageRating * 10) / 10.0;
            }
        }

        // 构建返回结果
        Map<String, Object> stats = new HashMap<>();
        stats.put("totalReviews", totalReviews);
        stats.put("goodReviews", goodReviews);
        stats.put("mediumReviews", mediumReviews);
        stats.put("badReviews", badReviews);
        stats.put("hasImageReviews", hasImageReviews);
        stats.put("averageRating", averageRating);

        return stats;
    }

    @Override
    public ReviewVO getReviewDetail(Integer id) {
        Reviews reviews = baseMapper.selectById(id);
        if (reviews == null) {
            throw new ObjectException("评价不存在");
        }
        return getReviewVO(reviews);
    }


    private ReviewVO getReviewVO(Reviews review) {
        ReviewVO vo = BeanUtil.copyProperties(review, ReviewVO.class);

        // 填充用户信息
        Optional.ofNullable(usersMapper.selectById(review.getUserId()))
                .ifPresent(member -> {
                    vo.setUsername(member.getNickname());
                    vo.setUserAvatar(member.getAvatar());
                });
        return vo;
    }
}
